import { createEle } from "./plugin/ele"
import ChuneditorAlert from "./plugin/alert" 
import $ from 'jquery';
export default class ChunEditor {
    JsDom;
    Range;
    Alert;

    constructor(el) {
        let mainBox =   $(`<div class="chunEditor"> </div>`)[0]
        $(el).append(mainBox)
        this.Alert = new ChuneditorAlert(mainBox)

        this.JsDom = $(`<div class="chunEditorContent" contenteditable="true"  role="textbox" autocorrect="off" autocomplete="off" spellcheck="false"> </div>`)[0]

        //顶部菜单
        // $(`<div class="chunEditorMenu"><ul>
        // <li data-type="B">B</li>
        // </ul></div>`).on("click", this.TopMenuClick).appendTo(dom) 
        mainBox.append(this.JsDom)

        this.SetHtml(`<div data-type="blockcard" data-tag="p"><p>111</p></div>`)
        //监听鼠标
        this.JsDom.addEventListener("mouseup", this.OnMouseup)
        this.JsDom.addEventListener("click", this.OnClick)
        this.JsDom.addEventListener("keyup", this.OnKeyUp)
        this.JsDom.addEventListener("keydown", this.OnKeyDown)
        this.JsDom.addEventListener("input", this.OnInput)

    }
    // ::selection

    SetHtml(v) {
        this.JsDom.innerHTML = v
    }

    TopMenuClick = (e) => {
        // e.stopPropagation();
        // e.preventDefault();
        // console.log($(e.target).data("type"), $(this.Range.startContainer).html())
        let type = $(e.target).data("type")

        //获取选中内容
        if (this.Range.startOffset == this.Range.endOffset) {
            //没有直接拖动选中 
            return false
        } else {
            //拖动选中 
        }


        switch (type) {
            case "B":
                //加粗 
                this.#replaceTool(type)
                break;

            default:
                break;
        }
    }

    //按键监听
    OnInput = (e) => {
        // console.log(e)
    }

    //按键监听
    OnKeyDown = (e) => {
        //回车  
        if (e.keyCode == 13) {
            e.preventDefault() //阻止默认
            e.stopPropagation();
            this.insertDom("p", "")
        } else {
            // e.preventDefault() //阻止默认
            // this.insertDom("p",{text:e.key}) 
        }

    }

    OnKeyUp = (e) => {
        this.saveRange();

    }

    OnClick = (e) => {
        //  console.log(e) 
        this.Alert.show(e)
    }


    OnMouseup = (e) => {

        this.saveRange();
        console.log(this.Range)
    }


    // 设置光标为 ele 元素之后
    setCursorAfter(ele) {
        // console.log("元素",ele)
        if (this.Range) {
            // if ($(ele).children("p").length>0) {
            //     ele = $(ele).children("p")[0]
            // }
            this.Range.setStartAfter(ele);
            this.Range.setEndAfter(ele)
        }

    }

    //光标在标內部
    setCursorInsert(ele) {
        if (this.Range) {
            if ($(ele).children("p").length > 0) {
                ele = $(ele).children("p")[0]
            }
            this.Range.setStart(ele, 0);
            this.Range.setEnd(ele, 0)
        }

    }

    // 获取光标位置相关信息
    saveRange() {
        let ele = this.JsDom
        const sel = window.getSelection();
        // console.log("获取光标",sel.rangeCount,sel)
        if (sel.rangeCount > 0) {
            this.Range = sel.getRangeAt(0);  // 获取到当前光标所在的元素区域对象  
            // 光标不在富文本框内，则将 range 改为 undefined  chunEditorContent
            if (!ele.contains(this.Range.startContainer)) {
                this.Range = undefined
                return
            }
            const focusPh = this.Range.startContainer
            if ($(focusPh).data("type") != undefined) {
                this.setCursorAfter(focusPh);  // 换行到外部
            }
        } else {
            this.Range = undefined
        }

        //console.log("获取光标",this.Range)
    }

    //插入内容
    insertDom = (type, ...args) => {
        let placeholderDom = createEle(type, ...args);
        if (this.Range) {  // 光标在富文本框内，插入到光标位置 

            console.log(this.getSelectedNodes())

            const focusPh = this.Range.startContainer;

            let rootP
            //inline和block 类型下不能插入别的标签
            rootP = $(focusPh).parents(".chunEditorContent div[data-type='inline']").last()
            if (rootP.length > 0) {
                this.setCursorAfter(rootP[0])
            }
            rootP = $(focusPh).parents(".chunEditorContent div[data-type='block']").last()
            if (rootP.length > 0) {
                this.setCursorAfter(rootP[0])
            }

            if (type == "p") {
                let rootP = $(focusPh).parents(".chunEditorContent div[data-tag='p']").last()
                if (rootP.length > 0) {
                    this.setCursorAfter(rootP[0])
                }
            }


            //这些type只能在根目录
            if (type == "table" || type == "title") {
                if (!this.isRootEditor(focusPh)) {
                    let rootP = $(focusPh).parents(".chunEditorContent div[data-tag='p']").last() 
                    if (rootP.length > 0 && rootP.parent(".chunEditorContent").length>0) {  
                            this.setCursorAfter(rootP[0])  
                    } else {
                        console.error(type + "不能插入此位置")
                        return false
                    }
                }
            }

            this.Range.insertNode(placeholderDom);
            this.Alert.hide()

        } else {  // 插入到末尾
            this.JsDom.appendChild(placeholderDom);
        }

        // 光标移到插入的元素后面 
        this.setCursorInsert(placeholderDom);
        //重载工具条
        this.Alert.reload()
    }

    //是否在编辑器根目录
    isRootEditor(el) {
        //简单判断
        return el.className == "chunEditorContent"
    }

    //获取内容
    getHtml = () => {

        return this.JsDom.innerHTML
    }

    //获取节点下的所有nodes
    getAllnodes = (node) => {
        let nodes = []
        function traverseNodes(node) {
            //判断该元素节点是否有子节点
            if (node.hasChildNodes) {
                //得到所有的子节点
                let sonnodes = node.childNodes;
                //遍历所哟的子节点
                for (var i = 0; i < sonnodes.length; i++) {
                    //得到具体的某个子节点
                    let sonnode = sonnodes.item(i);
                    //递归遍历 
                    nodes.push(sonnode)
                    traverseNodes(sonnode);
                }
            }
        }
        traverseNodes(node)
        return nodes;
    }

    //获取选择的内容
    getSelectedNodes() {
        if (this.Range) {
            let allnodes = this.getAllnodes(this.Range.commonAncestorContainer)
            let selectedNodes
            //相同选区
            if (this.Range.startContainer === this.Range.endContainer) {
                //相同位置
                if (this.Range.endOffset === this.Range.startOffset) {
                    selectedNodes = []  //没有选择
                } else {
                    selectedNodes = [this.Range.startContainer]
                }
            } else {
                selectedNodes = allnodes.slice(allnodes.indexOf(this.Range.startContainer), allnodes.indexOf(this.Range.endContainer) + 1)
            }
            return selectedNodes;
        }
        return [];
    }




    //指定位置替换
    #replaceTool(type) {
        let replacetext = ""
        console.log(this.getSelectedNodes())



        switch (type) {
            case "B":

                //#text
                this.getSelectedNodes().forEach(v => {
                    //已经是加粗状态  
                    if (v.parentNode.nodeName == "STRONG") {
                        $(v.parentNode).replaceWith($(v.parentNode).html())
                    } else {
                        replacetext = `<strong>${v.data.substring(start, stop)}</strong>`
                        let after = text.substring(0, start) + replacetext + text.substring(stop)
                        $(v).replaceWith(after)
                    }
                });

                break;

            default:
                break;
        }

    }

}